import React, { useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
import { message } from 'antd';
import { generationManager } from '@/utils/generation';
import { useI18n, toApiLanguageCode } from '@/utils/in18';
import { request } from '@/utils/request';
import { getStoredBearerToken, hasStoredToken } from '@/utils/auth';

export interface WorkListHandle {
    // 父组件可通过 ref 主动更新子组件中某个作品的公开状态
    applyWorkVisibility: (workId: number, isPublic: boolean) => void;
    // 父组件可通过 ref 主动从子组件移除某个作品
    removeWork: (workId: number) => void;
    // 立刻显示本地乐观的 loading 占位（在真实 pending 尚未返回前）
    showOptimisticLoading: () => void;
    // 滚动到 loading 占位区域
    scrollToLoading: () => void;
}

interface WorkListProps {
    // 卡片的通用样式（由父组件传入以保证 UI 一致）
    cardClass: string;
    // 点击生成结果预览图片的回调
    onOpenImage: (url: string) => void;
    // 点击作品卡片打开编辑弹层的回调
    onOpenWork: (work: any) => void;
    // 复用父组件的 messageApi，保证提示与全局一致
    messageApi?: ReturnType<typeof message.useMessage>[0];
}

const WorkList = React.forwardRef<WorkListHandle, WorkListProps>((props, ref) => {
    const { cardClass, onOpenImage, onOpenWork, messageApi } = props;
    const PAGE_SIZE = 8;

    // ===================== 生成队列相关（生成中/已完成） =====================
    // 说明：订阅全局 generationManager 的状态，渲染生成中任务与生成结果
    const [tick, setTick] = useState(0);
    useEffect(() => {
        const unsub = generationManager.subscribe(() => setTick((x) => x + 1));
        return () => { unsub(); };
    }, []);
    const genState = useMemo(() => generationManager.getState(), [tick]);

    // 虚拟进度（仅 UI 层）：记录 pending task 的百分比
    const [progressMap, setProgressMap] = useState<Record<number, number>>({});

    // 本地乐观占位：当点击生成按钮后，在真实任务 id 尚未出现前，立即展示 1 个占位
    const [ephemeralPendingCount, setEphemeralPendingCount] = useState<number>(0);
    const [ephemeralProgress, setEphemeralProgress] = useState<number>(0);
    const loadingAnchorRef = useRef<HTMLDivElement | null>(null);
    const refreshingRef = useRef<boolean>(false);
    const prevResultsCountRef = useRef<number>(0);

    // 当全局 pending 列表变化时，初始化/清理对应的进度条项
    useEffect(() => {
        const ids = genState.pendingTaskIds || [];
        setProgressMap((prev) => {
            const next: Record<number, number> = { ...prev };
            // 保留已有进度，不在短暂从 pending 列表移除时重置
            ids.forEach((id: number) => { if (!(id in next)) next[id] = 0; });
            // 仅在任务真正完成并出现在 results 中时才清理对应的进度记录
            try {
                const resultTaskIds = new Set<number>((genState.results || []).map((r: any) => Number(r?.task_id)).filter(Number.isFinite));
                Object.keys(next).forEach((k) => {
                    const n = Number(k);
                    if (resultTaskIds.has(n)) delete next[n];
                });
            } catch { }
            return next;
        });
    }, [tick]);

    // 周期性模拟进度增长（读最新的 pending 列表）
    useEffect(() => {
        const iv = window.setInterval(() => {
            const ids = generationManager.getState().pendingTaskIds || [];
            if (!ids || ids.length === 0) return;
            setProgressMap((prev) => {
                const next: Record<number, number> = { ...prev };
                ids.forEach((id: number) => {
                    const cur = Number(next[id] ?? 0);
                    if (cur >= 98) return; // 不超过 98%，等待真实结果
                    const inc = Math.floor(Math.random() * 6) + 2; // 2-7%
                    let nv = cur + inc;
                    if (nv > 98) nv = 98;
                    next[id] = nv;
                });
                return next;
            });
        }, 800);
        return () => { window.clearInterval(iv); };
    }, []);

    // 若出现真实的 pending 或 results 任务，则清空本地乐观占位
    useEffect(() => {
        if ((genState.pendingTaskIds || []).length > 0 || (genState.results || []).length > 0) {
            setEphemeralPendingCount(0);
            setEphemeralProgress(0);
        }
    }, [genState.pendingTaskIds, tick]);

    // 静默刷新：生成结果数量增加时，刷新第一页并合并
    const silentRefreshFirstPage = useCallback(async () => {
        if (refreshingRef.current) return;
        refreshingRef.current = true;
        try {
            const authHeader = getStoredBearerToken();
            if (!authHeader) return;
            const resp = await request.post('/api/work/listMyWorksRoute', { page: 1, page_size: PAGE_SIZE }, { headers: { Authorization: authHeader } });
            const list = Array.isArray(resp?.data?.data) ? resp.data.data : [];

            setMyWorks((prev) => {
                const seen = new Set<number>();
                const merged: any[] = [];
                // 先放服务器第一页（包含最新、且字段完整）
                for (const item of list) {
                    const wId = Number(item?.id);
                    if (Number.isFinite(wId) && !seen.has(wId)) {
                        seen.add(wId);
                        merged.push(item);
                    }
                }
                // 再保留旧列表中不在第一页的数据，避免丢失
                for (const item of prev) {
                    const wId = Number(item?.id);
                    if (Number.isFinite(wId) && !seen.has(wId)) {
                        seen.add(wId);
                        merged.push(item);
                    }
                }
                // 重置去重集合
                const newSeen = new Set<number>();
                for (const m of merged) {
                    const wId = Number(m?.id);
                    if (Number.isFinite(wId)) newSeen.add(wId);
                }
                dedupeSetRef.current = newSeen;
                return merged;
            });

            const received = list.length;
            if (received < PAGE_SIZE) {
                setHasMore(false);
                setPage(2); // 数值无所谓，hasMore 已经阻止下一页
            } else {
                setHasMore(true);
                setPage(2);
            }
        } catch (e) {
            // ignore
        } finally {
            refreshingRef.current = false;
        }
    }, []);

    useEffect(() => {
        const cur = (genState.results || []).length;
        const prev = prevResultsCountRef.current;
        if (cur > prev) {
            // 结果新增，静默刷新我的作品第一页
            silentRefreshFirstPage();
        }
        prevResultsCountRef.current = cur;
    }, [tick, genState.results, silentRefreshFirstPage]);

    // 本地乐观占位的进度模拟
    useEffect(() => {
        if (ephemeralPendingCount <= 0) return;
        const iv = window.setInterval(() => {
            setEphemeralProgress((p) => {
                const inc = Math.floor(Math.random() * 6) + 2; // 2-7%
                let nv = p + inc;
                if (nv > 98) nv = 98;
                return nv;
            });
        }, 800);
        return () => { window.clearInterval(iv); };
    }, [ephemeralPendingCount]);

    // ===================== 我的作品列表（懒加载 + 点赞） =====================
    const { locale, t } = useI18n();
    const [myWorks, setMyWorks] = useState<any[]>([]);
    const dedupeSetRef = useRef<Set<number>>(new Set());
    const [page, setPage] = useState<number>(1);
    // 分页大小使用常量 PAGE_SIZE，避免依赖顺序问题
    const [hasMore, setHasMore] = useState<boolean>(true);
    const [loadingWorks, setLoadingWorks] = useState<boolean>(false);
    const sentinelRef = useRef<HTMLDivElement | null>(null);

    // 拉取我的作品列表（分页+去重）
    const fetchMyWorks = useCallback(async () => {
        if (loadingWorks || !hasMore) return;
        if (!hasStoredToken()) return;
        setLoadingWorks(true);
        try {
            const authHeader = getStoredBearerToken();
            if (!authHeader) return;
            const resp = await request.post('/api/work/listMyWorksRoute', { page, page_size: PAGE_SIZE }, { headers: { Authorization: authHeader } });
            const list = Array.isArray(resp?.data?.data) ? resp.data.data : [];

            setMyWorks((prev) => {
                const next = [...prev];
                const seen = dedupeSetRef.current;
                for (const item of list) {
                    const wId = Number(item?.id);
                    if (Number.isFinite(wId) && !seen.has(wId)) {
                        seen.add(wId);
                        next.push(item);
                    }
                }
                return next;
            });

            const received = list.length;
            if (received < PAGE_SIZE) {
                setHasMore(false);
            } else {
                setPage((p) => p + 1);
            }
        } catch (e) {
            // 忽略错误
        } finally {
            setLoadingWorks(false);
        }
    }, [page, loadingWorks, hasMore]);

    // 首次进入加载第一页
    useEffect(() => {
        fetchMyWorks();
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, []);

    // 监听底部哨兵进行懒加载
    useEffect(() => {
        if (!sentinelRef.current) return;
        const el = sentinelRef.current;
        const io = new IntersectionObserver((entries) => {
            entries.forEach((entry) => {
                if (entry.isIntersecting) {
                    fetchMyWorks();
                }
            });
        }, { root: null, rootMargin: '200px', threshold: 0 });
        io.observe(el);
        return () => { io.disconnect(); };
    }, [fetchMyWorks]);

    // 点赞/取消点赞（乐观更新）
    const handleToggleLike = useCallback(async (work: any) => {
        if (!work || !work.id) return;
        const authHeader = getStoredBearerToken();
        if (!authHeader) return;
        const lang = toApiLanguageCode(locale as any);

        setMyWorks((prev) => prev.map((w) => {
            if (w.id !== work.id) return w;
            const nextLiked = !Boolean(w.is_liked);
            const nextCount = Math.max(0, Number(w.likes_count || 0) + (nextLiked ? 1 : -1));
            return { ...w, is_liked: nextLiked, likes_count: nextCount };
        }));

        try {
            const resp = await request.post('/api/work/toggleWorkLikeRoute', { work_id: work.id, language: lang }, { headers: { Authorization: authHeader } });
            const serverLiked = Boolean(resp?.data?.is_liked);
            const serverCount = (resp?.data?.likes_count ?? resp?.data?.like_count);
            setMyWorks((prev) => prev.map((w) => w.id === work.id ? {
                ...w,
                is_liked: serverLiked,
                likes_count: Number.isFinite(Number(serverCount)) ? Number(serverCount) : w.likes_count,
            } : w));
            if (resp?.data?.success && messageApi) {
                messageApi.success(serverLiked ? t('CreatImg.liked') : t('CreatImg.unliked'));
            }
        } catch (e) {
            // 回滚
            setMyWorks((prev) => prev.map((w) => {
                if (w.id !== work.id) return w;
                const prevLiked = Boolean(work.is_liked);
                const diff = prevLiked ? 1 : -1;
                const prevCount = Math.max(0, Number(w.likes_count || 0) + diff);
                return { ...w, is_liked: prevLiked, likes_count: prevCount };
            }));
            if (messageApi) messageApi.error(t('CreatImg.operation_failed'));
        }
    }, [locale, messageApi]);

    // 暴露给父组件的操作：更新公开状态 / 删除 / 显示乐观 loading / 滚动到 loading
    useImperativeHandle(ref, () => ({
        applyWorkVisibility: (workId: number, isPublic: boolean) => {
            setMyWorks((prev) => prev.map((w) => w.id === workId ? { ...w, is_public: isPublic } : w));
        },
        removeWork: (workId: number) => {
            setMyWorks((prev) => prev.filter((w) => w.id !== workId));
            dedupeSetRef.current.delete(Number(workId));
        },
        showOptimisticLoading: () => {
            setEphemeralPendingCount((c) => Math.max(1, c));
            setEphemeralProgress(0);
        },
        scrollToLoading: () => {
            try {
                loadingAnchorRef.current?.scrollIntoView({ behavior: 'smooth', block: 'center' });
            } catch { }
        },
    }), []);

    // ===================== 渲染 =====================
    // 结果与我的作品根据图片 URL 和作品 ID 做去重，避免重复展示
    const resultsImageUrlSet = useMemo(() => {
        const s = new Set<string>();
        try {
            (genState.results || []).forEach((r: any) => {
                const u = String(r?.images?.[0]?.url || r?.output_work?.image_url || '');
                if (u) s.add(u);
            });
        } catch { }
        return s;
    }, [tick]);

    const resultsWorkIdSet = useMemo(() => {
        const s = new Set<number>();
        try {
            (genState.results || []).forEach((r: any) => {
                const id = Number(r?.output_work?.id);
                if (Number.isFinite(id)) s.add(id);
            });
        } catch { }
        return s;
    }, [tick]);

    const myWorksFiltered = useMemo(() => {
        if ((!resultsImageUrlSet || resultsImageUrlSet.size === 0) && (!resultsWorkIdSet || resultsWorkIdSet.size === 0)) return myWorks;
        return myWorks.filter((w: any) => {
            const wId = Number(w?.id);
            if (Number.isFinite(wId) && resultsWorkIdSet.has(wId)) return false;
            const u = String(w?.image_url || '');
            return u ? !resultsImageUrlSet.has(u) : true;
        });
    }, [myWorks, resultsImageUrlSet, resultsWorkIdSet]);

    const getResultImageUrl = useCallback((r: any): string => {
        const a = String(r?.images?.[0]?.url || '');
        if (a) return a;
        const b = String(r?.output_work?.image_url || '');
        return b || '';
    }, []);

    const handleToggleLikeForResult = useCallback(async (r: any) => {
        const work = r?.output_work;
        const workId = Number(work?.id);
        if (!Number.isFinite(workId)) return;
        const authHeader = getStoredBearerToken();
        if (!authHeader) return;
        const lang = toApiLanguageCode(locale as any);

        const prevLiked = Boolean(work?.is_liked);
        const nextLiked = !prevLiked;
        const prevCount = Number(work?.likes_count || 0);
        const nextCount = Math.max(0, prevCount + (nextLiked ? 1 : -1));

        // 乐观更新到全局结果集中
        try {
            generationManager.updateResultWork(workId, { is_liked: nextLiked, likes_count: nextCount });
        } catch { }

        try {
            const resp = await request.post('/api/work/toggleWorkLikeRoute', { work_id: workId, language: lang }, { headers: { Authorization: authHeader } });
            const serverLiked = Boolean(resp?.data?.is_liked);
            const serverCountRaw = (resp?.data?.likes_count ?? resp?.data?.like_count);
            const serverCount = Number.isFinite(Number(serverCountRaw)) ? Number(serverCountRaw) : nextCount;
            generationManager.updateResultWork(workId, { is_liked: serverLiked, likes_count: serverCount });
            if (resp?.data?.success && messageApi) messageApi.success(serverLiked ? t('CreatImg.liked') : t('CreatImg.unliked'));
        } catch (e) {
            // 回滚
            generationManager.updateResultWork(workId, { is_liked: prevLiked, likes_count: prevCount });
            if (messageApi) messageApi.error(t('CreatImg.operation_failed'));
        }
    }, [locale, messageApi]);

    const isEmpty = (
        ephemeralPendingCount === 0 &&
        genState.pendingTaskIds.length === 0 &&
        genState.results.length === 0 &&
        myWorksFiltered.length === 0
    );

    return (
        <div className='mt-4'>
            <div className='flex flex-col gap-2'>
                {/* ===================== 生成中任务占位卡片 ===================== */}
                <div ref={loadingAnchorRef} />
                <div className='grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-4 gap-2 md:gap-3 lg:gap-4'>
                    {Array.from({ length: ephemeralPendingCount }).map((_, idx) => {
                        const pct = Math.max(0, Math.min(100, Math.floor(ephemeralProgress)));
                        return (
                            <div key={`ephemeral_${idx}`} className={`relative overflow-hidden rounded-lg ${cardClass} p-2`} style={{ aspectRatio: '1024 / 1712' }}>
                                <div className='absolute inset-0 flex items-center justify-center'>
                                    <div className='w-24 flex flex-col items-center'>
                                        <div className='w-full h-2 bg-[#ffffff20] rounded overflow-hidden mb-2'>
                                            <div style={{ width: `${pct}%` }} className='h-full bg-gradient-to-r from-pink-400 to-pink-600 transition-[width]'></div>
                                        </div>
                                        {/* <div className='text-[12px] text-[#9ea3a8]'>{t('CreatImg.generating')}</div> */}
                                        <div className='text-[12px] text-[#9ea3a8] mt-1'>{pct}%</div>
                                    </div>
                                </div>
                            </div>
                        );
                    })}
                    {genState.pendingTaskIds.map((id: number) => {
                        const pct = Math.max(0, Math.min(100, Math.floor(progressMap[id] ?? 0)));
                        return (
                            <div key={`pending_${id}`} className={`relative overflow-hidden rounded-lg ${cardClass} p-2`} style={{ aspectRatio: '1024 / 1712' }}>
                                <div className='absolute inset-0 flex items-center justify-center'>
                                    <div className='w-24 flex flex-col items-center'>
                                        <div className='w-full h-2 bg-[#ffffff20] rounded overflow-hidden mb-2'>
                                            <div style={{ width: `${pct}%` }} className='h-full bg-gradient-to-r from-pink-400 to-pink-600 transition-[width]'></div>
                                        </div>
                                        <div className='text-[12px] text-[#9ea3a8] mt-1'>{pct}%</div>
                                        {/* <div className='text-[12px] text-[#9ea3a8]'>{t('CreatImg.generating_with_id').replace('{id}', String(id))}</div> */}
                                    </div>
                                </div>
                            </div>
                        );
                    })}

                    {/* ===================== 已完成结果卡片 ===================== */}
                    {genState.results.map((r: any) => {
                        const url = getResultImageUrl(r);
                        const work = r?.output_work;
                        const liked = Boolean(work?.is_liked);
                        const likes = Number(work?.likes_count || 0);
                        const isPublic = Boolean(work?.is_public);
                        return (
                            <div key={r.task_id} className={`relative overflow-hidden rounded-lg ${cardClass}`} style={{ aspectRatio: '1024 / 1712' }} onClick={() => { if (work && Number.isFinite(Number(work.id))) { onOpenWork({ ...work, image_url: work?.image_url || url || '' }); } else if (url) { onOpenImage(url); } }}>
                                {url ? (
                                    <img src={url} alt={`task_${r.task_id}`} className='w-full h-full' />
                                ) : (
                                    <div className='absolute inset-0 flex items-center justify-center text-xs text-[#9ea3a8]'>{t('CreatImg.no_image')}</div>
                                )}

                                {isPublic && (
                                    <div className='absolute top-2 left-2 z-10'>
                                        <span className='px-2 py-0.5 rounded-full bg-pink-500/90 text-white text-[10px] font-semibold'>{t('CreatImg.public_label')}</span>
                                    </div>
                                )}

                                {Number.isFinite(Number(work?.id)) && (
                                    <button
                                        onClick={(e) => { e.stopPropagation(); handleToggleLikeForResult(r); }}
                                        className='absolute top-2 right-2 flex items-center gap-1 bg-black/50 hover:bg-black/60 text-white text-xs px-2 py-1 rounded-full'
                                        aria-label={t('CreatImg.aria_toggle_like')}
                                    >
                                        <span className={liked ? 'text-[#ef4444]' : 'text-white'}>
                                            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 6 3.99 4 6.5 4c1.74 0 3.41.99 4.22 2.44h.56C12.09 4.99 13.76 4 15.5 4 18.01 4 20 6 20 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" /></svg>
                                        </span>
                                        <span>{likes}</span>
                                    </button>
                                )}

                                {/* <div className='absolute bottom-1 left-1 right-1 text-center pointer-events-none'>
                                <span className='px-2 py-0.5 rounded bg-black/60 text-white text-[10px]'>{t('CreatImg.task_label').replace('{id}', String(r.task_id))}</span>
                            </div> */}
                            </div>
                        );
                    })}

                    {/* ===================== 我的作品列表卡片 ===================== */}
                    {myWorksFiltered.map((w: any) => {
                        const img = String(w?.image_url || '');
                        const liked = Boolean(w?.is_liked);
                        const likes = Number(w?.likes_count || 0);
                        const isPublic = Boolean(w?.is_public);
                        return (
                            <div key={`work_${w.id}`} className={`relative overflow-hidden rounded-lg ${cardClass}`} style={{ aspectRatio: '1024 / 1712' }} onClick={() => onOpenWork(w)}>
                                {img ? (
                                    <img src={img} alt={`work_${w.id}`} className='w-full h-full object-cover' />
                                ) : (
                                    <div className='absolute inset-0 flex items-center justify-center text-xs text-[#9ea3a8]'>{t('CreatImg.no_image')}</div>
                                )}

                                {isPublic && (
                                    <div className='absolute top-2 left-2 z-10'>
                                        <span className='px-2 py-0.5 rounded-full bg-pink-500/90 text-white text-[10px] font-semibold'>{t('CreatImg.public_label')}</span>
                                    </div>
                                )}

                                <button
                                    onClick={(e) => { e.stopPropagation(); handleToggleLike(w); }}
                                    className='absolute top-2 right-2 flex items-center gap-1 bg-black/50 hover:bg-black/60 text-white text-xs px-2 py-1 rounded-full'
                                    aria-label={t('CreatImg.aria_toggle_like')}
                                >
                                    <span className={liked ? 'text-[#ef4444]' : 'text-white'}>
                                        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M12 21.35l-1.45-1.32C5.4 15.36 2 12.28 2 8.5 2 6 3.99 4 6.5 4c1.74 0 3.41.99 4.22 2.44h.56C12.09 4.99 13.76 4 15.5 4 18.01 4 20 6 20 8.5c0 3.78-3.4 6.86-8.55 11.54L12 21.35z" /></svg>
                                    </span>
                                    <span>{likes}</span>
                                </button>
                            </div>
                        );
                    })}
                </div>

                {/* 懒加载哨兵与加载状态 */}
                <div ref={sentinelRef} />
                {loadingWorks && (
                    <div className='text-center text-xs text-[#9ea3a8] py-2'>{t('CreatImg.loading')}</div>
                )}
                {!hasMore && myWorksFiltered.length > 0 && (
                    <div className='text-center text-[10px] text-[#9ea3a8] py-2'>{t('CreatImg.no_more')}</div>
                )}
            </div>

            {/* 空状态（当生成中、结果与我的作品均为空时显示） */}
            {isEmpty && (
                <div className='mt-8 text-center text-[#9ea3a8] text-sm'>
                    {t('CreatImg.no_media_found')}
                </div>
            )}
        </div>
    );
});

export default WorkList;


